#include "Stegos.hpp"

#include <iostream>
#include <sstream>

#include "FileUtils.hpp"
#include "Stegutils.hpp"


namespace Stegos
{

void insert(int pDepth, const str_t& pStegfile, const str_t& pCoverfile, const str_t& pOutputfile)
{
    ui_t width = 0, height = 0;
    vuc_t imagedata;
    if(FileUtils::openPPMFile(pCoverfile, width, height, imagedata))
    {
        vuc_t::iterator imagedataiter = imagedata.begin();

        vuc_t stegdata;
        FileUtils::openBinaryFile(pStegfile, stegdata);

        //encode size

        vuc_t stegsize = StegUtils::encodeIntToCharArray(stegdata.size());
        imagedataiter = StegUtils::encode(pDepth, stegsize, imagedataiter, imagedata);


        //encode stegdata into imagedata
        imagedataiter = StegUtils::encode(pDepth, stegdata, imagedataiter, imagedata);

        std::stringstream ppmheader;
        ppmheader<<"P6\n"<<width<<" "<<height<<"\n255\n";
        vuc_t header;
        FileUtils::stringToUnsignedCharVector(ppmheader.str(), header);
        FileUtils::writeBinaryFile(pOutputfile, header);
        FileUtils::writeBinaryFile(pOutputfile, imagedata);
    }
}

void recover(int pDepth, const str_t& pCoverfile, const str_t& pOutputfile)
{

    ui_t width = 0, height = 0;
    vuc_t imagedata;
    if(FileUtils::openPPMFile(pCoverfile, width, height, imagedata))
    {

        vuc_t::const_iterator imagedataiter = imagedata.begin();

        //decode stegsize
        vuc_t stegsizedata;
        imagedataiter = StegUtils::decode(pDepth, 4, imagedataiter, imagedata, stegsizedata);
        if(imagedataiter == imagedata.end())
        {
            std::cout<<"ERROR"<<std::endl;
            return;
        }
        ui_t stegsize = StegUtils::decodeIntFromCharArray(stegsizedata);

        //decode stegdata
        vuc_t recoverstegdata;
        imagedataiter = StegUtils::decode(pDepth, stegsize, imagedataiter, imagedata, recoverstegdata);
        FileUtils::writeBinaryFile(pOutputfile, recoverstegdata);
    }
}

void info(ui_t pDepth, const str_t& pCoverfile)
{
    ui_t width = 0, height = 0;
    vuc_t imagedata;
    FileUtils::openPPMFile(pCoverfile, width, height, imagedata);
    std::cout<<"Steg object size for cover file "<<pCoverfile<<" using bit depth:"<<pDepth<<" "<<StegUtils::getMaxStegObjectSize(pDepth, imagedata)<<" bytes";
}

}
